home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / strategy / xpuzzles.3 / xpuzzles / xpuzzles-5.3.1 / xrubik / RubikU.c < prev    next >
C/C++ Source or Header  |  1996-02-05  |  7KB  |  269 lines

  1. /*
  2. # X-BASED RUBIK'S CUBE(tm)
  3. #
  4. #  RubikU.c
  5. #
  6. ###
  7. #
  8. #  Copyright (c) 1994 - 96    David Albert Bagley, bagleyd@hertz.njit.edu
  9. #
  10. #                   All Rights Reserved
  11. #
  12. #  Permission to use, copy, modify, and distribute this software and
  13. #  its documentation for any purpose and without fee is hereby granted,
  14. #  provided that the above copyright notice appear in all copies and
  15. #  that both that copyright notice and this permission notice appear in
  16. #  supporting documentation, and that the name of the author not be
  17. #  used in advertising or publicity pertaining to distribution of the
  18. #  software without specific, written prior permission.
  19. #
  20. #  This program is distributed in the hope that it will be "playable",
  21. #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  23. #
  24. */
  25.  
  26. /* Undo algorithm */
  27.  
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <X11/IntrinsicP.h>
  31. #include <X11/Intrinsic.h>
  32. #include <X11/StringDefs.h>
  33. #include <X11/CoreP.h>
  34. #include "RubikP.h"
  35. #include "Rubik2dP.h"
  36. #include "Rubik3dP.h"
  37.  
  38. typedef struct _MoveRecord
  39. {
  40.   /* int face, direction, control; */
  41.   unsigned short int packed; /* This makes assumptions on the data. */
  42.   int position; /* Do not make assumptions on this one. */
  43. } MoveRecord;
  44.  
  45. typedef struct _MoveStack
  46. {
  47.   MoveRecord move;
  48.   struct _MoveStack *previous, *next;
  49. } MoveStack;
  50.  
  51. static MoveStack *currMove, *lastMove, *firstMove;
  52. static int count;
  53. RubikLoc *startLoc[MAXFACES] = {
  54.   NULL, NULL, NULL, NULL, NULL, NULL
  55. };
  56.  
  57. static void InitStack();
  58. static void PushStack();
  59. static void PopStack();
  60. static int EmptyStack();
  61. static void FlushStack();
  62.  
  63. static void InitStack()
  64. {
  65.   if (!(lastMove = (MoveStack *) malloc(sizeof(MoveStack))))
  66.     XtError("Not enough memory, exiting.");
  67.   if (!(firstMove = (MoveStack *) malloc(sizeof(MoveStack))))
  68.     XtError("Not enough memory, exiting.");
  69.   firstMove->previous = lastMove->next = NULL;
  70.   firstMove->next = lastMove;
  71.   lastMove->previous = firstMove;
  72.   count = 0;
  73. }
  74.  
  75. static void PushStack(move)
  76.   MoveRecord move;
  77. {
  78.   if (!(currMove = (MoveStack *) malloc(sizeof(MoveStack))))
  79.     XtError("Not enough memory, exiting.");
  80.   lastMove->previous->next = currMove;
  81.   currMove->previous = lastMove->previous;
  82.   currMove->next = lastMove;
  83.   lastMove->previous = currMove;
  84.   currMove->move = move;
  85.   count++;
  86. }
  87.  
  88. static void PopStack(move)
  89.   MoveRecord *move;
  90. {
  91.   *move = lastMove->previous->move;
  92.   currMove = lastMove->previous;
  93.   lastMove->previous->previous->next = lastMove;
  94.   lastMove->previous = lastMove->previous->previous;
  95.   (void) free((void *) currMove);
  96.   count--;
  97. }
  98.  
  99. static int EmptyStack()
  100. {
  101.   return (lastMove->previous == firstMove);
  102. }
  103.  
  104. static void FlushStack()
  105. {
  106.   while (lastMove->previous != firstMove) {
  107.     currMove = lastMove->previous;
  108.     lastMove->previous->previous->next = lastMove;
  109.     lastMove->previous = lastMove->previous->previous;
  110.     (void) free((void *) currMove);
  111.   }
  112.   count = 0;
  113. }
  114.  
  115. /**********************************/
  116.  
  117. void InitMoves()
  118. {
  119.   InitStack();
  120. }
  121.  
  122. static void WriteMove(move, face, position, direction, control)
  123.   MoveRecord *move;
  124.   int face, position, direction, control;
  125. {
  126.   /* move->face = face; move->direction = direction;
  127.   move->control = control; */
  128.   move->packed = ((control & 0xF) << 8) + ((direction & 0xF) << 4) +
  129.     (face & 0xF);
  130.   move->position = position;
  131. }
  132.  
  133. static void ReadMove(face, position, direction, control, move)
  134.   int *face, *position, *direction, *control;
  135.   MoveRecord move;
  136. {
  137.   /* *face = move.face; *direction = move.direction;
  138.   *control = move.control; */
  139.   *face = move.packed & 0xF;
  140.   *direction = (move.packed >> 4) & 0xF;
  141.   *control = (move.packed >> 8) & 0xF;
  142.   *position = move.position;
  143. }
  144.  
  145. void PutMove(face, position, direction, control)
  146.   int face, position, direction, control;
  147. {
  148.   MoveRecord move;
  149.  
  150.   WriteMove(&move, face, position, direction, control);
  151.   PushStack(move);
  152. }
  153.  
  154. void GetMove(face, position, direction, control)
  155.   int *face, *position, *direction, *control;
  156. {
  157.   MoveRecord move;
  158.  
  159.   PopStack(&move);
  160.   ReadMove(face, position, direction, control, move);
  161. }
  162.  
  163. int MadeMoves()
  164. {
  165.   return !EmptyStack();
  166. }
  167.  
  168. void FlushMoves(w)
  169.   RubikWidget w;
  170. {
  171.   int face, position;
  172.  
  173.   FlushStack();
  174.   for (face = 0; face < MAXFACES; face++)
  175.     for (position = 0; position < w->rubik.sizeSize; position++) {
  176.       startLoc[face][position].face =
  177.         w->rubik.cubeLoc[face][position].face;
  178.       startLoc[face][position].rotation =
  179.         w->rubik.cubeLoc[face][position].rotation;
  180.     }
  181. }
  182.  
  183. int NumMoves()
  184. {
  185.   return count;
  186. }
  187.  
  188. void ScanMoves(fp, w, moves)
  189.   FILE *fp;
  190.   RubikWidget w;
  191.   int moves;
  192. {
  193.   int face, position, direction, control, k;
  194.   char c;
  195.  
  196.   for (k = 0; k < moves; k++) {
  197.     while ((c = getc(fp)) != EOF && c != SYMBOL);
  198.     (void) fscanf(fp, "%d %d %d %d", &face, &position, &direction, &control);
  199.     MoveRubik(w, face, position, direction, control);
  200.   }
  201. }
  202.  
  203. void PrintMoves(fp)
  204.   FILE *fp;
  205. {
  206.   int face, position, direction, control, counter = 0;
  207.  
  208.   currMove = firstMove->next;
  209.   (void) fprintf(fp, "moves\tface\tpos\tdir\tcon\n"); 
  210.   while (currMove != lastMove) {
  211.     ReadMove(&face, &position, &direction, &control, currMove->move);
  212.     (void) fprintf(fp, "%d%c\t%d\t%d\t%d\t%d\n",
  213.       ++counter, SYMBOL, face, position, direction, control); 
  214.     currMove = currMove->next;
  215.   }
  216. }
  217.  
  218. void ScanStartPosition(fp, w)       
  219.   FILE *fp;
  220.   RubikWidget w;
  221. {
  222.   int face, position, num;
  223.   char c;
  224.  
  225.   while ((c = getc(fp)) != EOF && c != SYMBOL);
  226.   for (face = 0; face < MAXFACES; face++)
  227.     for (position = 0; position < w->rubik.sizeSize; position++) {
  228.       (void) fscanf(fp, "%d ", &num);
  229.       startLoc[face][position].face = num;
  230.       if (w->rubik.orient) {
  231.         (void) fscanf(fp, "%d ", &num);
  232.         startLoc[face][position].rotation = num;
  233.       }
  234.     }
  235. }
  236.  
  237. void PrintStartPosition(fp, w)       
  238.   FILE *fp;
  239.   RubikWidget w;
  240. {
  241.   int face, position;
  242.  
  243.   (void) fprintf(fp, "\nstartingPosition%c\n", SYMBOL);
  244.   for (face = 0; face < MAXFACES; face++) {
  245.     for (position = 0; position < w->rubik.sizeSize; position++) {
  246.       (void) fprintf(fp, "%d ", startLoc[face][position].face);
  247.       if (w->rubik.orient)
  248.         (void) fprintf(fp, "%d  ", startLoc[face][position].rotation);
  249.     }
  250.     (void) fprintf(fp, "\n");
  251.   }
  252. }
  253.  
  254. void SetStartPosition(w)       
  255.   RubikWidget w;
  256. {
  257.   int face, position;
  258.  
  259.   for (face = 0; face < MAXFACES; face++)
  260.     for (position = 0; position < w->rubik.sizeSize; position++) {
  261.       w->rubik.cubeLoc[face][position].face =
  262.         startLoc[face][position].face;
  263.       if (w->rubik.orient)
  264.          w->rubik.cubeLoc[face][position].rotation =
  265.            startLoc[face][position].rotation;
  266.     }
  267.   DrawAllPolyhedrons(w);
  268. }
  269.